package domain;

import exception.IllegalHourException;
import exception.IllegalMinuteException;

public final class PTime implements Comparable<PTime> {
	
	private final String INVALID_HOUR = "Invalid Hour. Hour must be between 0 and 23";
	private final String INVALID_MINUTE = "Invalid Minute. Minute must be between 0 and 59";
	
	public static final int MAX_HOUR = 23;
	public static final int MIN_HOUR = 0;
	public static final int MAX_MINUTE = 59;
	public static final int MIN_MINUTE = 0;
	
	private int hour;
	private int minute;
	
	public PTime(int h, int m) throws IllegalHourException, IllegalMinuteException {
		this.setHour(h);
		this.setMinute(m);
	}

	public int getHour() {
		return hour;
	}

	public void setHour(int hour) throws IllegalHourException {
		if (hour < MIN_HOUR || hour > MAX_HOUR) {
			throw new IllegalHourException(INVALID_HOUR);
		}
		this.hour = hour;
	}
	
	public void addHour(int hour) {
		try {
			this.setHour((this.getHour() + hour) % (MAX_HOUR + 1));
		} catch (IllegalHourException e) {
		}
	}

	public int getMinute() {
		return minute;
	}

	public void setMinute(int minute) throws IllegalMinuteException {
		if (minute < MIN_MINUTE || minute > MAX_MINUTE) {
			throw new IllegalMinuteException(INVALID_MINUTE);
		}
		this.minute = minute;
	}
	
	public void addMinute(int minute) {
		try {
			this.setMinute((this.getMinute() + minute) % (MAX_MINUTE + 1));
		} catch (IllegalMinuteException e) {
		}
	}
	
	@Override
	public boolean equals(Object o) {
		if (o == null || this.getClass() != o.getClass()) {
			return false;
		}
		if (o == this) {
			return true;
		}
		return ((PTime) o).getHour() == this.getHour() && ((PTime) o).getMinute() == this.getMinute();
	}
	
	@Override
	public int hashCode() {
		return 3600 * this.getHour() + 60 * this.getMinute();
	}
	
	@Override
	public String toString() {
		if (this.getMinute() == 0) {
			return String.format("%dh", this.getHour());
		}
		return String.format("%dh%dmin", this.getHour(), this.getMinute());
	}
	
	public static PTime sum(PTime a, PTime b) {
		PTime c = null;
		try {
			c = new PTime(a.getHour(), a.getMinute());
		} catch (Exception e) {
		}
		c.addHour(b.getHour());
		c.addMinute(b.getMinute());
		return c;
	}

	@Override
	public int compareTo(PTime other) {
		final int BEFORE = -1;
		final int EQUAL = 0;
		final int AFTER = 1;
		
		if (this.getHour() < other.getHour()) {
			return BEFORE;
		} else if (this.getHour() == other.getHour()) {
			if (this.getMinute() < other.getMinute()) {
				return BEFORE;
			} else if (this.getMinute() == other.getMinute()) {
				return EQUAL;
			} else {
				return AFTER;
			}
		} else {
			return AFTER;
		}
	}

}
